package com.pair.micro.common.network;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.pair.micro.common.network.intercepter.MicroNetworkInterceptor;
import com.pair.micro.common.network.intercepter.MicroRetryInterceptor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 嘉悦云网络请求 使用okhttp，失败自动重连3次，每次连接超时时间为30秒
 *
 * @author menglt
 * @since 2020-01-09
 */
@Slf4j
public class MicroNetwork {

  /** 字符集 */
  public static final String CHARACTER_ENCODING = "utf-8";

  /** Json请求格式 */
  public static final MediaType MEDIATYPE_JSON = MediaType.parse("application/json; charset=utf-8");

  /** form文件请求格式 */
  public static final MediaType MEDIATYPE_FILE =
      MediaType.parse("multipart/form-data; charset=utf-8");

  /** 安卓Apk请求格式 */
  public static final MediaType MEDIATYPE_APK =
      MediaType.parse("application/vnd.android.package-archive; charset=utf-8");

  /** PKCS12证书请求格式 */
  public static final MediaType MEDIATYPE_PKCS12 =
      MediaType.parse("application/x-pkcs12; charset=utf-8");

  /**
   * GET请求
   *
   * @param api
   * @return
   * @throws IOException
   */
  public static String GetJson(String api) throws IOException {
    log.debug("JycloudNetwork发起GetJson请求 api -> [" + api + "]");
    Request.Builder builder = new Request.Builder();
    Request request = builder.url(api).get().build();
    Response response =
        (new OkHttpClient()
                .newBuilder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .callTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .addInterceptor(new MicroRetryInterceptor(3))
                .addNetworkInterceptor(new MicroNetworkInterceptor()))
            .build()
            .newCall(request)
            .execute();
    String resp = "";
    if (ObjectUtil.isNotNull(response)) {
      ResponseBody responseBody = response.body();
      if (ObjectUtil.isNotNull(responseBody)) {
        resp = responseBody.string();
      }
      response.close();
    }
    log.debug("JycloudNetwork结束GetJson请求 api -> [" + api + "] 响应回参：[" + resp + "]");
    return resp;
  }

  /**
   * POST请求（入参格式为json，放入body中）
   *
   * @param api
   * @param jsonParam
   * @return
   * @throws IOException
   */
  public static String PostJson(String api, String jsonParam) throws IOException {
    log.debug("JycloudNetwork发起PostJson请求 api -> [" + api + "] 请求入参：[" + jsonParam + "]");
    RequestBody body = RequestBody.create(MEDIATYPE_JSON, jsonParam);
    Request.Builder builder = new Request.Builder();
    Request request = builder.url(api).post(body).build();
    Response response =
        (new OkHttpClient()
                .newBuilder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .callTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .addInterceptor(new MicroRetryInterceptor(3))
                .addNetworkInterceptor(new MicroNetworkInterceptor()))
            .build()
            .newCall(request)
            .execute();
    String resp = "";
    if (ObjectUtil.isNotNull(response)) {
      ResponseBody responseBody = response.body();
      if (ObjectUtil.isNotNull(responseBody)) {
        resp = responseBody.string();
      }
      response.close();
    }
    log.debug("JycloudNetwork结束PostJson请求 api -> [" + api + "] 响应回参：[" + resp + "]");
    return resp;
  }

  /**
   * @name: PostFile
   * @description POST请求（入参为文件）
   * @author menglt
   * @date 2021/10/30 15:32
   * @param api
   * @param file
   * @param fileKey
   * @param paramMap
   * @return: java.lang.String
   */
  public static String PostFile(String api, File file, String fileKey, Map<String, String> paramMap)
      throws IOException {
    log.debug(
        "JycloudNetwork发起PostFile请求 api -> ["
            + api
            + "] 请求入参：["
            + JSON.toJSONString(paramMap)
            + "]");
    RequestBody fileBody = RequestBody.create(MEDIATYPE_FILE, file);

    if (StrUtil.isBlank(fileKey)) {
      fileKey = "file";
    }

    String fileTypeKey = "";
    String sourceKey = "";
    String saveTypeKey = "superFile";
    String purpose = "";

    String prefix = "";
    String suffix = "";

    if (paramMap.containsKey("fileTypeKey")) {
      fileTypeKey = paramMap.get("fileTypeKey");
    }

    if (paramMap.containsKey("sourceKey")) {
      sourceKey = paramMap.get("sourceKey");
    }

    if (paramMap.containsKey("saveTypeKey")) {
      saveTypeKey = paramMap.get("saveTypeKey");
    }

    if (paramMap.containsKey("purpose")) {
      purpose = paramMap.get("purpose");
    }

    if (paramMap.containsKey("prefix")) {
      prefix = paramMap.get("prefix");
    }

    if (paramMap.containsKey("suffix")) {
      suffix = paramMap.get("suffix");
    }

    RequestBody requestBody =
        new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(fileKey, file.getName(), fileBody)
            .addFormDataPart("fileTypeKey", fileTypeKey)
            .addFormDataPart("sourceKey", sourceKey)
            .addFormDataPart("saveTypeKey", saveTypeKey)
            .addFormDataPart("purpose", purpose)
            .addFormDataPart("suffix", suffix)
            .addFormDataPart("prefix", prefix)
            .build();
    Request request = new Request.Builder().url(api).post(requestBody).build();
    Response response =
        (new OkHttpClient()
                .newBuilder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .callTimeout(600, TimeUnit.SECONDS)
                .readTimeout(300, TimeUnit.SECONDS)
                .writeTimeout(300, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .addInterceptor(new MicroRetryInterceptor(3))
                .addNetworkInterceptor(new MicroNetworkInterceptor()))
            .build()
            .newCall(request)
            .execute();
    String resp = "";
    if (ObjectUtil.isNotNull(response)) {
      ResponseBody responseBody = response.body();
      if (ObjectUtil.isNotNull(responseBody)) {
        resp = responseBody.string();
      }
      response.close();
    }
    log.debug("JycloudNetwork结束PostFile请求 api -> [" + api + "] 响应回参：[" + resp + "]");
    return resp;
  }

  /**
   * @name: GetFileStream
   * @description 获取文件流
   * @author menglt
   * @date 2021/10/30 15:32
   * @param fileUrl
   * @return: java.io.InputStream
   */
  public static InputStream GetFileStream(String fileUrl) throws IOException {
    log.debug("JycloudNetwork发起GetFileStream请求 fileUrl -> [" + fileUrl + "]");
    Request.Builder builder = new Request.Builder();
    Request request = builder.url(fileUrl).get().build();
    Response response =
        (new OkHttpClient()
                .newBuilder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .callTimeout(600, TimeUnit.SECONDS)
                .readTimeout(300, TimeUnit.SECONDS)
                .writeTimeout(300, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .addInterceptor(new MicroRetryInterceptor(3))
                .addNetworkInterceptor(new MicroNetworkInterceptor()))
            .build()
            .newCall(request)
            .execute();
    InputStream fileStream = null;
    if (ObjectUtil.isNotNull(response)) {
      ResponseBody responseBody = response.body();
      if (ObjectUtil.isNotNull(responseBody)) {
        fileStream = responseBody.byteStream();
      }
      response.close();
    }

    if (ObjectUtil.isNotNull(fileStream)) {
      log.debug("JycloudNetwork结束GetFileStream请求 fileUrl -> [" + fileUrl + "] 文件存在，已返回文件流");
    } else {
      log.debug("JycloudNetwork结束GetFileStream请求 fileUrl -> [" + fileUrl + "] 文件不存在");
    }

    return fileStream;
  }
}
